/*********************************************************************************
 *      Copyright:  (C) 2025 ZYT
 *                  All rights reserved.
 *
 *       Filename:  pack.c
 *    Description:  This file pack data
 *                 
 *        Version:  1.0.0(01/05/25)
 *         Author:  Zhang yuting <zhangyuting@163.com>
 *      ChangeLog:  1, Release initial version on "01/05/25 14:08:34"
 *                 
 ********************************************************************************/
#include "pack.h"

int pack_data(packet_t *pack, uint8_t *data, int bytes )
{
	if( NULL == pack)
	{
		log_error("pointer [pack] is NULL\n");
		return -1;
	}

	memset(data, 0, bytes);

	snprintf(data, bytes, "sn:%s|time:%s|temp:%.3f", pack->dev_sn, pack->dev_time, pack->dev_temp);

	log_debug("pack_data successfully!\n");
	return 0;
}

int pack_data_json( packet_t *pack, uint8_t *buf, int bytes )
{
	int         rv;

	if( !pack )
	{
		log_error("%s() Invalid input arguments\n", __func__);
		return -1;
	}

	memset(buf, 0, bytes);
	snprintf(buf, bytes, "{\"device\":\"%s\", \"times\":\"%s\",\"temperature\":\"%.4f\",\"illuminance\":\"%.4f\",\"air\":\"%.4f\"}", pack->dev_sn, pack->dev_time, pack->dev_temp, pack->dev_lux, pack->dev_con);

	rv = strlen(buf);

	return rv;
}


int pack_data_tlv( packet_t *pack, uint8_t *buf, int bytes )
{
	int                 offset = 0;
	uint16_t            crc;
	char                *time_str = pack->dev_time;
	int                 year, month, day, hour, minute, second;
	int                 tag_temperature = 1;
	int					tag_lux = 2;
	int 				tag_con = 3;

	if( !pack )
	{
		log_error("%s() Invalid input arguments\n", __func__);
		return -1;
	}

	memset(buf, 0, bytes);
	//Header
	*(uint16_t *)buf = htons(0xFEDD);
	offset += 2;

	//Tag
	buf[offset] = tag_temperature;
	offset += 1;       //写入数据偏移量
	offset += 2;        //跳过数据

	//Value:sn
	strncpy((char *)(buf+offset), pack->dev_sn, 10);
	offset += 10;

	//Value:time
	sscanf(time_str, "%4d%2d%2d %2d:%2d:%2d", &year, &month, &day, &hour, &minute, &second);
	buf[offset++] = (uint8_t)(year - 2000);
	buf[offset++] = (uint8_t)month;
	buf[offset++] = (uint8_t)day;
	buf[offset++] = (uint8_t)hour;
	buf[offset++] = (uint8_t)minute;
	buf[offset++] = (uint8_t)second;

	//Value:temp
	buf[offset++] = (int)pack->dev_temp;        //整数部分
	buf[offset++] = ( ( ((int)(pack->dev_temp*10000))%10000 ) / 100 );        //小数部分1
	buf[offset++] = ( ( ((int)(pack->dev_temp*10000))%10000 ) % 100 );        //小数部分2

	//Length
	*(uint16_t *)(buf+3) = (offset-5);

	// 新增光照TLV
	buf[offset++] = tag_lux;  // 光照标签
	*(uint16_t *)(buf + offset) = htons(4);  // 长度=4字节(uint32)
	offset += 2;
	*(uint32_t *)(buf + offset) = htonl(pack->dev_lux);  // 写入光照值（网络字节序）
	offset += 4;

	// 新增空气质量TLV
	buf[offset++] = tag_con;  // 空气质量标签
	*(uint16_t *)(buf + offset) = htons(4);  // 长度=4字节(uint32)
	offset += 2;
	*(uint32_t *)(buf + offset) = htonl(pack->dev_con);  // 写入空气质量值（网络字节序）
	offset += 4;

	//CRC
	crc = crc_itu_t(buf, offset);
	*(uint16_t *)(buf+offset) = htons(crc);
	offset += 2;

	return offset;
}

static uint16_t crc_itu_t(const uint8_t *data, size_t length)
{
	uint16_t          crc = 0xFFFF;
	size_t            i, j;

	for (i=0; i<length; i++)
	{
		crc ^= ((uint16_t)data[i] << 8);

		for(j=0; j<8; j++)
		{
			if (crc & 0x8000)
			{
				crc = (crc << 1) ^ CRC16_ITU_T_POLY;
			}
			else
			{
				crc <<= 1;
			}
		}
	}

	return crc;
}

